package com.smallkingson.ylib.view;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.RectF;
import android.os.Build;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import com.smallkingson.ylib.view.utils.YViews;

public class YPopupBinder implements View.OnClickListener {

    private final FrameLayout contentView;
    private float elevation = 50;
    private View clickView;
    private View popupView;
    private FrameLayout rootLayout;
    private final FrameLayout.LayoutParams popupLp;
    private int divideHeight = 5;
    private final Point contentViewPoint;
    private ShaderLayout popupContainer;
    private final FrameLayout.LayoutParams popupContainerLp;
    private int radius = 10;
    private int color;
    private int duration=100;
    private float start= 0.9f;;


    private YPopupBinder(Activity activity, View clickView, View popupView) {


        //init
        this.clickView = clickView;
        this.popupView = popupView;
        contentView = YViews.getContentView(activity);
        popupContainer = new ShaderLayout(clickView.getContext());
        popupContainerLp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
        contentViewPoint = YViews.getViewOnScreenXY(contentView);
        popupLp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout
                .LayoutParams.WRAP_CONTENT);

        popupContainer.setRadius(radius);
        //root add to content
        rootLayout = new FrameLayout(clickView.getContext());
        rootLayout.setClickable(true);
        rootLayout.setVisibility(View.GONE);
        rootLayout.setId(android.R.id.background);
        FrameLayout.LayoutParams rootLp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup
                .LayoutParams.MATCH_PARENT);
        contentView.addView(rootLayout, rootLp);
        //popupContainer add to root
        rootLayout.addView(popupContainer, popupContainerLp);
        ViewCompat.setElevation(popupContainer, elevation);
        //popupView add to popupContainer
        popupContainer.addView(popupView, popupLp);
        //set listener
        clickView.setOnClickListener(this);
        rootLayout.setOnClickListener(this);
    }

    public static YPopupBinder create(Activity activity, View clickView, View popupView) {
        return new YPopupBinder(activity, clickView, popupView);
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    @Override
    public void onClick(View v) {

        switch (v.getId()) {
            case android.R.id.background: {
                dismiss();
                break;
            }
            default: {
                show();
            }
        }
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private void dismiss() {
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(1, start);
        valueAnimator.setDuration(duration);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float animatedValue = (float) animation.getAnimatedValue();
                popupContainer.setAlpha(animatedValue);
                popupContainer.setScaleX(animatedValue);
                popupContainer.setScaleY(animatedValue);
            }
        });
        valueAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                rootLayout.setVisibility(View.GONE);
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
        valueAnimator.start();
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private void show() {
        Point contentViewPoint = YViews.getViewOnScreenXY(contentView);
        Point point = YViews.getViewOnScreenXY(clickView);
        popupContainerLp.setMargins(point.x - contentViewPoint.x, point.y - contentViewPoint.y + clickView.getHeight() + divideHeight,
                0, 0);
        //如果超过右边屏
//                    Yr.d(popupContainerLp.leftMargin, popupContainer.getWidth(), popupContainer.getMeasuredWidth(), getWidthAndHeight
//                            (popupContainer));
        Point popupContainerPoint = getWidthAndHeight(popupContainer);
        int right = popupContainerPoint.x + popupContainerLp.leftMargin;
        int contentRight = contentViewPoint.x + contentView.getWidth();
        if (right > contentRight) {
            int left = popupContainerLp.leftMargin - (right - contentRight);
            popupContainerLp.setMargins(left < 0 ? 0 : left, popupContainerLp.topMargin, popupContainerLp.rightMargin, popupContainerLp
                    .bottomMargin);
//                        Yr.d(popupContainerLp.leftMargin);
        }
        popupContainer.setLayoutParams(popupContainerLp);
        popupContainer.postInvalidate();
        //动画前的准备
        popupContainer.setPivotX(popupContainerPoint.x/2);
        popupContainer.setAlpha(start);
        popupContainer.setScaleX(start);
        popupContainer.setScaleY(start);
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(start, 1);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Float animatedValue = (Float) animation.getAnimatedValue();
                popupContainer.setAlpha(animatedValue);
                popupContainer.setScaleX(animatedValue);
                popupContainer.setScaleY(animatedValue);
            }
        });
        valueAnimator.setDuration(duration).start();

        rootLayout.setVisibility(View.VISIBLE);
    }

    public static Point getWidthAndHeight(View v) {

        int w = View.MeasureSpec.makeMeasureSpec(0,
                View.MeasureSpec.UNSPECIFIED);
        int h = View.MeasureSpec.makeMeasureSpec(0,
                View.MeasureSpec.UNSPECIFIED);
        v.measure(w, h);
        int height = v.getMeasuredHeight();
        int width = v.getMeasuredWidth();
        return new Point(width, height);
    }
    //**********************************************************set and get***


    public int getColor() {
        return color;
    }

    public void setColor(int color) {
        this.color = color;
        popupContainer.setColor(color);
    }

    public int getDivideHeight() {
        return divideHeight;
    }

    public void setDivideHeight(int divideHeight) {
        this.divideHeight = divideHeight;
    }

    public int getRadius() {
        return radius;
    }

    public void setRadius(int radius) {
        this.radius = radius;
        popupContainer.setRadius(radius);
    }

    /*
            inner class
             */
    public class ShaderLayout extends FrameLayout {

        private Paint paint;
        int radius = 10;
        private RectF rect;

        private int color;
        public ShaderLayout(Context context) {
            this(context, null);
        }

        @TargetApi(Build.VERSION_CODES.HONEYCOMB)
        public ShaderLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
            setWillNotDraw(false);
            setLayerType(View.LAYER_TYPE_SOFTWARE, null);
            rect = new RectF();
            BlurMaskFilter bmf = new BlurMaskFilter(radius, BlurMaskFilter.Blur.OUTER);
            paint = new Paint();
            paint.setColor(Color.BLACK);
            paint.setMaskFilter(bmf);
            setPadding(radius, radius, radius, radius);
        }

        @Override
        protected void onDraw(Canvas canvas) {

            rect.set(radius, radius, getWidth() - radius, getHeight() - radius);
            canvas.drawRoundRect(rect, radius / 2, radius / 2, paint);
        }

        /*
        set and get
         */

        public int getColor() {
            return color;
        }

        public void setColor(int color) {
            this.color = color;
            paint.setColor(color);
            postInvalidate();
        }

        public int getRadius() {
            return radius;
        }

        public void setRadius(int radius) {
            this.radius = radius;
            setPadding(radius, radius, radius, radius);
            paint.setMaskFilter(new BlurMaskFilter(radius, BlurMaskFilter.Blur.OUTER));
            postInvalidate();
        }
    }
}